#include "bsp_delay.h"
#include "bsp_led.h"
#include "bsp_beep.h"
#include "bsp_int.h"

void short_delay(volatile unsigned int n)
{
    while(n--){
        ;
    }
}

/* sleep 1ms */
void delay(volatile unsigned int m){
    while(m--){
        short_delay(0x7ff);
    }
}


#include "bsp_delay.h"
#include "bsp_int.h"
#include "bsp_led.h"
#include "bsp_beep.h"

/*
 * @description 	: 延时初始化
 * @param  			: 无
 * @return 			: 无
 */
void delay_init(void)
{
	/* GPT1_CR 清零 */
	GPT1->CR = 0;

	/* GPT1->CR 软件复位 */
	GPT1->CR |= (1 << 15);
	while(((GPT1->CR >> 15) & 0x01));

	
	GPT1->CR |= (1 << 6);		/* CLKSRC bit[8:6], 1 时钟源选择ipg_clk */
	GPT1->CR |= (1 << 1);		/* ENMODE bit[1], 1 reset mode */
								/* FRR bit[9], 0 reset mode */

	/* GPT1_PR 分频 */
	GPT1->PR &= ~(0xFFF << 0);
	GPT1->PR |= (65 << 0);		/* 66Mhz/66=1MHz */



	//GPT1->OCR[0] = 1000000/10;	/* GPT1输出比较通道1 */
	GPT1->OCR[0] = 0xFFFFFFFF;		/* GPT1输出比较通道1 */

#if 0
	GPT1->IR &= ~(1 << 0);
	GPT1->IR |= (1 << 0);		/* 使能GPT1输出比较通道1中断 */

	GIC_EnableIRQ(GPT1_IRQn);
	system_irqhandler_register(GPT1_IRQn, gpt_system_irq_handler_t, NULL);
	gpt_irq_enable(GPT1);		/* GPT1 输出比较中断使能 */
#endif

	gpt_enable(GPT1);			/* GPT1 enable*/
}

/*
 * @description 	: 使能GPT输出比较通道1中断。
 * @param – base 	: GPT寄存器
 * @return 			: 无
 */
void gpt_enable(GPT_Type *base)
{
	base->CR |= (1 << 0);
}

/*
 * @description 	: 使能GPT输出比较通道1中断。
 * @param – base 	: GPT寄存器
 * @return 			: 无
 */
void gpt_disable(GPT_Type *base)
{
	base->CR &= ~(1 << 0);
}

/*
 * @description 	: 使能GPT输出比较通道1中断。
 * @param – base 	: GPT寄存器
 * @return 			: 无
 */
void gpt_irq_enable(GPT_Type *base)
{
	base->IR |= (1 << 0);
}

/*
 * @description 	: 禁用GPT输出比较通道1中断。
 * @param – base 	: GPT寄存器
 * @return 			: 无
 */
void gpt_irq_disable(GPT_Type *base)
{
	base->IR &= ~(1 << 0);
}

/*
 * @description 	: 清除中断标志位。
 * @param – base 	: GPT寄存器
 * @return 			: 无
 */
void gpt_cleanIrqFlag(GPT_Type *base)
{
	base->SR |= (1 << 0);
}

/*
 * @description 	: 清除中断标志位。
 * @param – base 	: GPT寄存器
 * @return 			: 无
 */
void gpt_restart_timer(GPT_Type *base, int value)
{
	base->CR &= ~(1 << 0);		/* 关闭GPT定时器 */
	base->OCR[0] = value;
	base->CR |= (1 << 0);		/* 启用GPT定时器 */
}

/*
 * @description 		: GPT中断处理函数。
 * @param – irq 		: 中断ID
 * @param – userparam 	: 用户注册参数
 * @return 				: 无
 */
void gpt_system_irq_handler_t(IRQn_Type irq, void *userparam)
{
	static int led_state = 0;

	if(GPT1->SR & (1 << 0))
	{
		led_state = !led_state;
		led_switch(LED_0, led_state);
		beep_switch(led_state);

		//gpt_restart_timer(GPT1, 1000000/10);

		/* 清除中断标志位 */
		gpt_cleanIrqFlag(GPT1);
	}
}


/*
 * @description 		: 高精度延时函数微秒，基于GPT定时器
 * @param – us 			: 延时微秒数
 * @return 				: 无
 */
void delay_us(int time_us)
{
	int oldvalue = 0;
	int newvalue = 0;
	int value = 0;
	
	oldvalue = GPT1->CNT;
	
	while(1)
	{
		newvalue = GPT1->CNT;
		if(newvalue != oldvalue){
			if(newvalue < oldvalue){
				value += 0xFFFFFFFF - oldvalue + newvalue;
			}
			else{
				value += newvalue - oldvalue;
			}
			oldvalue = newvalue;

			if(value >= time_us)
				break;
		}
	}
}

/*
 * @description 		: 高精度延时函数毫秒，基于GPT定时器
 * @param – us 			: 延时毫秒数
 * @return 				: 无
 */
void delay_ms(int time_ms)
{
	int i = 0;

	for(i=0; i<time_ms; i++){
		delay_us(1000);
	}
}